<template>
  <div class="app-container">
    <div class="header">
      <div class="op">
        <!-- <ManualUpload v-model="fileList"></ManualUpload> -->
      </div>
      <el-form
        ref="formRef"
        :model="definitionForm"
        :rules="definitionRules"
        label-width="auto"
        inline
        class="deform"
      >
        <el-form-item label="定义名称" prop="formName">
          <el-input v-model="definitionForm.formName" />
        </el-form-item>
        <el-form-item label="定义编码" prop="formCode">
          <el-input v-model="definitionForm.formCode" />
        </el-form-item>
        <el-form-item label="定义描述" prop="description">
          <el-input
            v-model="definitionForm.description"
            type="textarea"
            maxlength="500"
            :rows="1"
          />
        </el-form-item>
        <el-form-item label="适用范围" prop="tags">
          <el-select v-model="definitionForm.tags" multiple filterable>
            <el-option
              v-for="item in tagsOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="显示顺序" prop="displayOrder">
          <el-input-number v-model="definitionForm.displayOrder" :min="0" />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="definitionForm.status">
            <el-radio label="禁用" :value="0"></el-radio>
            <el-radio label="启用" :value="1"></el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="附件" prop="attachmentIds">
          <div style="height: 66px; display: flex">
            <manual-upload
              ref="uploadRef"
              v-model="definitionForm.attachmentIds"
              :auto-upload="false"
              :limit="1"
              :disabled="definitionForm?.attachmentIds.split(',') > 0 || upFileList.length > 0"
              accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
              :style="{ width: '250px' }"
              @on-success="handleSuccess"
              @on-change="handleChange"
              @remove="handleRemove"
            >
              <el-button
                type="primary"
                plain
                :disabled="definitionForm?.attachmentIds.split(',') > 0 || upFileList.length > 0"
              >
                模板上传
              </el-button>
              <el-tooltip placement="right-start" effect="light">
                <template #content>
                  <div
                    style="
                      padding: 5px;
                      width: 300px;
                      font-size: 16px;
                      line-height: 24px;
                      color: #606266;
                    "
                  >
                    模板用于填报时的下载和导入功能。用户需要手动下载模板然后填写对应的内容，
                    最后通过导入功能快速填充在线表格。所以请保证模板与在线表格的统一性。
                    (可以通过同步至在线表格选项帮助快速创建在线表格)
                  </div>
                  <!-- 仅支持xlsx文件，并且上传的模板里面不要有跨文件的取值公式。 -->
                </template>
                <el-icon style="margin-left: 10px" color="#606266" class="ml-1 cursor-pointer">
                  <QuestionFilled />
                </el-icon>
              </el-tooltip>
            </manual-upload>
          </div>
        </el-form-item>
        <el-form-item prop="echoUniver" style="vertical-align: top;">
          <el-checkbox
            v-model="definitionForm.echoUniver"
            label="同步至在线表格"
            @change="syncUniver"
          />
        </el-form-item>
        <el-form-item>
          <div style="height: 66px">
            <el-button type="primary" @click="back">保存提交并返回</el-button>
          </div>
        </el-form-item>
      </el-form>
    </div>
    <div class="content">
      <template v-if="workbookData">
        <univer-sheet
          ref="univerSheet"
          class="univerSheet"
          :data="workbookData"
          @cellSelection="cellSelection"
          @deleteSheet="deleteSheet"
          @renameSheet="renameSheet"
        />
        <div class="type-define-container">
          <el-card class="type-define-card">
            <div style="text-align: right">
              <el-tooltip placement="right-start" effect="light">
                <template #content>
                  <div
                    style="
                      padding: 5px;
                      width: 300px;
                      font-size: 16px;
                      line-height: 24px;
                      color: #606266;
                    "
                  >
                    统计范围用于对用户填写的范围进行规范然后用于数据统计。
                    同样导入也只会导入统计范围划定部分的单元格数据。
                  </div>
                  <!-- 仅支持xlsx文件，并且上传的模板里面不要有跨文件的取值公式。 -->
                </template>
                <el-icon color="#606266" style="margin-bottom: 10px" class="cursor-pointer">
                  <QuestionFilled />
                </el-icon>
              </el-tooltip>
            </div>

            <el-form v-model="currentFormElement" :model="currentFormElement">
              <el-form-item label="统计名称" prop="name">
                <el-input v-model="currentFormElement.name" :readonly="isReadonly" />
              </el-form-item>
              <el-form-item label="统计字段" prop="code">
                <el-input v-model="currentFormElement.code" :readonly="isReadonly" />
              </el-form-item>
              <el-form-item label="统计描述" prop="description">
                <el-input
                  v-model="currentFormElement.description"
                  type="textarea"
                  maxlength="500"
                  :rows="3"
                  :readonly="isReadonly"
                />
              </el-form-item>
              <el-form-item
                v-if="currentFormElement.position"
                label="统计范围"
                prop="__position"
                :rules="[
                  {
                    required: true,
                    pattern: /^([A-Z]+)(\d+)(:([A-Z]+)(\d+))?$/,
                    message: '请输入正确的格式，例如：A1:A10',
                  },
                ]"
              >
                <el-input
                  v-model="currentFormElement.__position"
                  @blur="handleFormElement(currentFormElement)"
                />
              </el-form-item>
              <div style="display: flex; justify-content: space-between">
                <el-button type="text" @click="formElementsMap = new Map()">
                  清空所有统计配置
                </el-button>
                <el-button type="text" @click="handleProtectionRange(currentFormElement)">
                  保护/解锁单元格
                </el-button>
              </div>
            </el-form>
            <div class="header-config-container">
              <template v-for="v in isValueFormElements" :key="v.position">
                <div>
                  <p style="font-weight: bold">
                    {{ v.sheetName ? `${v.sheetName}!` : '' }}{{ v.name || '未命名' }}:
                  </p>
                  <p style="padding-left: 20px; font-size: 14px">
                    <span style="vertical-align: middle; cursor: pointer" @click="selectionArea(v)">
                      {{ getExcelColumn(v.position.split(',')[1])
                      }}{{ parseInt(v.position.split(',')[0]) + 1 }}:{{
                        getExcelColumn(v.position.split(',')[3])
                      }}{{ parseInt(v.position.split(',')[2]) + 1 }}
                    </span>
                    <el-icon
                      style="vertical-align: middle; cursor: pointer; margin-left: 5px"
                      @click="formElementsMap.delete(`${v.sheetId}!${v.position}`)"
                    >
                      <el-tooltip class="item" effect="dark" content="删除">
                        <Close />
                      </el-tooltip>
                    </el-icon>
                  </p>
                </div>
              </template>
            </div>
          </el-card>
        </div>
      </template>
    </div>
  </div>
</template>

<script setup lang="ts">
import FormAPI from '@/api/batch/form.api';
import type { FormInstance, FormRules } from 'element-plus';
import univerSheet from './univerSheet.vue';
import ResolveExcel from './resolve';
import ManualUpload from '@/components/Upload/ManualUpload.vue';
const route = useRoute(); // 获取路由参数
const router = useRouter(); // 路由跳转
const categoryId: any = route.query.categoryId; // 关联的表单类型id
const id: any = route.query.id as String; // 表单定义id
const formRef = ref<FormInstance>();
const formElementsMap = ref<Map<string, any>>(new Map());
const activeCell = ref<any>(null);
const workbookData = ref<any>(null);
const currentInstance: any = getCurrentInstance();
const protectionRange = ref<any>({});
const tagsOptions = reactive<any[]>([
  {
    label: '月度',
    value: '月度',
  },
  {
    label: '季度',
    value: '季度',
  },
  {
    label: '年度',
    value: '年度',
  },
  {
    label: '自定义',
    value: '自定义',
  },
]);

// const activeCells = ref<any[]>([]);
// 当前所选单元格输入框的值
const isReadonly = computed(() => {
  return !activeCell.value;
});
const isValueFormElements = computed(() => {
  const ret: any = [];
  console.log('formElementsMap.value-', formElementsMap.value);
  formElementsMap.value.forEach((v) => {
    if (v.code) {
      ret.push(v);
    }
  });
  return ret;
});
const currentFormElement = computed<any>(() => {
  let current = activeCell.value
    ? formElementsMap.value.get(
        `${activeCell.value.sheetId}!${activeCell.value.startRow},${activeCell.value.startColumn},${activeCell.value.endRow},${activeCell.value.endColumn}`
      )
    : null;
  if (activeCell.value && !current) {
    const __position =
      activeCell.value.startRow == activeCell.value.endRow &&
      activeCell.value.startColumn == activeCell.value.endColumn
        ? `${getExcelColumn(activeCell.value.startColumn)}${parseInt(
            activeCell.value.startRow + 1
          )}`
        : `${getExcelColumn(activeCell.value.startColumn)}${parseInt(
            activeCell.value.startRow + 1
          )}:${getExcelColumn(activeCell.value.endColumn)}${parseInt(activeCell.value.endRow + 1)}`;
    const templateData = {
      name: undefined,
      code: undefined,
      type: 'number',
      sheetName: activeCell.value.sheetName,
      sheetId: activeCell.value.sheetId,
      position: `${activeCell.value.startRow},${activeCell.value.startColumn},${activeCell.value.endRow},${activeCell.value.endColumn}`,
      __position,
      required: true,
      validation: [],
      description: '',
      defaultValue: '',
      readOnly: false,
      group: 'group1',
    };
    formElementsMap.value.set(`${templateData.sheetId}!${templateData.position}`, templateData);
  }
  return activeCell.value ? current : {};
});
function wordToPosition(word: string) {
  const pattern = /^([A-Z]+)(\d+)(:([A-Z]+)(\d+))?$/;
  const match = word.match(pattern);
  if (match) {
    const startRow = parseInt(match[2]) - 1; // 减1是因为Excel的行号从1开始
    const startColumn = getExcelColumnIndex(match[1]); // 转换为列号
    const endRow = match[4] ? parseInt(match[5]) - 1 : startRow; // 结束行号，如果未指定则默认为开始行号
    const endColumn = match[5] ? getExcelColumnIndex(match[4]) : startColumn; // 结束列号，如果未指定则默认为开始列号
    return {
      startRow,
      startColumn,
      endRow,
      endColumn,
    };
  }
  return null;
}
function handleFormElement(formElement: any) {
  if (formElement.__position) {
    const match = wordToPosition(formElement.__position);
    if (match) {
      const { startRow, startColumn, endRow, endColumn } = match;
      const matchFormElement = formElementsMap.value.get(
        `${formElement.sheetId}!${startRow},${startColumn},${endRow},${endColumn}`
      );
      if (!matchFormElement) {
        const oldPosition = formElement.position;
        formElementsMap.value.delete(oldPosition);
        formElement.position = `${startRow},${startColumn},${endRow},${endColumn}`;
        formElementsMap.value.set(`${formElement.sheetId}!${formElement.position}`, {
          ...toRaw(formElement),
        });
      }
      currentInstance.refs.univerSheet.setSlection(formElement.__position, {
        sheetId: formElement.sheetId,
      });
    }
  }
}
async function handleProtectionRange(formElement: any) {
  if (!formElement.__position) {
    return;
  }
  const match = wordToPosition(formElement.__position);
  if (!match) {
    return;
  }
  const { startRow, startColumn, endRow, endColumn } = match;
  const keys = Object.keys(protectionRange.value);
  const key = `${formElement.sheetId}!${startRow},${startColumn},${endRow},${endColumn}`;
  if (protectionRange.value[key]) {
    currentInstance.refs.univerSheet.setProtection(formElement, {
      addProtection: false,
      ruleIds: [protectionRange.value[key].ruleId],
    });
    delete protectionRange.value[key];
    return;
  }
  let isOverhas = false;
  const currentFormElement = {
    startRow: parseInt(formElement.position.split(',')[0]),
    startColumn: getExcelColumnIndex(formElement.position.split(',')[1]),
    endRow: parseInt(formElement.position.split(',')[2]),
    endColumn: getExcelColumnIndex(formElement.position.split(',')[3]),
  };
  keys.forEach((key) => {
    const positionStr = key.split('!')[1];
    const positionArr = positionStr.split(',');
    const currentPosition = {
      startRow: parseInt(positionArr[0]),
      startColumn: getExcelColumnIndex(positionArr[1]),
      endRow: parseInt(positionArr[2]),
      endColumn: getExcelColumnIndex(positionArr[3]),
    };
    const rowOverlap =
      currentPosition.startRow <= currentFormElement.endRow &&
      currentPosition.endRow >= currentFormElement.startRow;
    // 检查列范围是否重叠
    const colOverlap =
      currentPosition.startColumn <= currentFormElement.endColumn &&
      currentPosition.endColumn >= currentFormElement.startColumn;
    // 如果行和列范围都重叠，则认为它们重叠
    if (rowOverlap && colOverlap) {
      isOverhas = true;
      return;
    }
  });
  if (isOverhas) {
    ElMessage.error('框选的区域有重叠，请先解锁在进行操作');
    return;
  }
  currentInstance.refs.univerSheet.setProtection(
    formElement,
    {
      addProtection: true,
    },
    ({ ruleId }: any) => {
      protectionRange.value[key] = {
        ruleId: ruleId,
        sheetName: formElement.sheetName,
        position: formElement.position,
        meanposition: formElement.__position,
        sheetId: formElement.sheetId,
      };
    }
  );
}
// 单元格点击事件处理
const cellSelection = (cell: any) => {
  activeCell.value = cell;
};
const deleteSheet = (option: any) => {
  const sheetId = option.worksheet.getSheetId();
  formElementsMap.value.forEach((element, key): any => {
    if (sheetId === element.sheetId) {
      formElementsMap.value.delete(key);
    }
  });
};
const renameSheet = (option: any) => {
  const sheetId = option.sheetId;
  const newName = option.newName;
  formElementsMap.value.forEach((element): any => {
    if (sheetId === element.sheetId) {
      element.sheetName = newName;
    }
  });
};
// 单元格编辑结束事件处理
// const editEnded = (cell: any) => {
//   const current = formElementsMap.value.get(`${cell.row},${cell.column}`);
//   if (current && !current.name) {
//     current.name = cell.value;
//     current.defaultValue = cell.value;
//   }
// };
const upFileList = ref<any[]>([]);
const definitionForm = reactive<any>({
  id: undefined,
  formName: '',
  formCode: '',
  description: '',
  displayOrder: 0,
  status: 1,
  attachmentIds: '',
  echoUniver: true,
});

const definitionRules: FormRules = {
  formName: [
    { required: true, message: '请输入定义名称', trigger: 'blur' },
    { min: 1, max: 500, message: '长度在 1 到 500', trigger: 'blur' },
  ],
  formCode: [
    { required: true, message: '请输入定义编码', trigger: 'blur' },
    { min: 1, max: 500, message: '长度在 1 到 500', trigger: 'blur' },
  ],
  description: [
    { required: true, message: '请输入描述', trigger: 'blur' },
    { min: 1, max: 500, message: '长度在 1 到 500', trigger: 'blur' },
  ],
};

const initSchema = (schema: string) => {
  try {
    const schemaData = JSON.parse(schema);
    console.log('schemaData', schemaData);
    workbookData.value = schemaData.univerContent || {};
    schemaData.formElements.forEach((element: any) => {
      formElementsMap.value.set(`${element.sheetId}!${element.position}`, {
        ...element,
        __position: `${getExcelColumn(element.position.split(',')[1])}${
          parseInt(element.position.split(',')[0]) + 1
        }:${getExcelColumn(element.position.split(',')[3])}${
          parseInt(element.position.split(',')[2]) + 1
        }`,
      });
    });
    return schemaData;
  } catch (error: any) {
    console.error(`schema解析失败:${error.message}`);
    workbookData.value = {};
  }
};
const initPermission = (schemaData: any) => {
  nextTick(() => {
    if (!schemaData.permissions || schemaData.permissions.length === 0) {
      return;
    }
    schemaData.permissions.forEach((element: any) => {
      console.log('element-', element);
      currentInstance.refs.univerSheet.setProtection(
        {
          sheetId: element.sheetId,
          __position: element.meanposition,
          position: element.position,
        },
        {
          addProtection: true,
        },
        ({ ruleId }: any) => {
          protectionRange.value[`${element.sheetId}!${element.position}`] = {
            ruleId,
            sheetName: element.sheetName,
            position: element.position,
            meanposition: element.meanposition,
            sheetId: element.sheetId,
          };
        }
      );
    });
  });
};
onMounted(() => {
  if (id) {
    FormAPI.getDefinitionDetail(id).then((data: any) => {
      definitionForm.id = data.id;
      definitionForm.formName = data.formName;
      definitionForm.formCode = data.formCode;
      definitionForm.description = data.description;
      definitionForm.displayOrder = data.displayOrder;
      definitionForm.status = data.status;
      definitionForm.attachmentIds = data.attachmentIds;
      definitionForm.categoryId = data.categoryId;
      definitionForm.schemaJson = data.schemaJson;
      if (data.tags) {
        definitionForm.tags = data.tags.split(',');
      } else {
        definitionForm.tags = [];
      }
      if (data.schemaJson) {
        const jsonSchema = initSchema(data.schemaJson);
        nextTick(() => {
          initPermission(jsonSchema);
        });
      } else {
        workbookData.value = {};
      }
    });
  } else {
    workbookData.value = {};
  }
});
// 根据列的坐标展示excel的英文版字母
function getExcelColumn(number: number | string) {
  if (typeof number !== 'number') {
    number = parseInt(number);
  }
  let column = '';
  while (number >= 0) {
    const remainder = number % 26;
    column = String.fromCharCode(remainder + 65) + column;
    number = Math.floor(number / 26) - 1;
    if (number < 0) break;
  }
  return column;
}
// 根据列的英文名称获取列的坐标
function getExcelColumnIndex(column: string) {
  let index = 0;
  for (let i = 0; i < column.length; i++) {
    const charCode = column.charCodeAt(i) - 64;
    index = index * 26 + charCode;
  }
  return index - 1;
}
function selectionArea(row: any) {
  const [startRow, startColumn, endRow, endColumn] = row.position.split(',');
  currentInstance.refs.univerSheet.setSlection(
    `${getExcelColumn(startColumn)}${parseInt(startRow) + 1}:${getExcelColumn(endColumn)}${
      parseInt(endRow) + 1
    }`,
    {
      sheetId: row.sheetId,
    }
  );
}
// const reset = () => {
//   formRef.value?.resetFields();
//   formRef.value?.clearValidate();
//   definitionForm.id = undefined;
//   definitionForm.description = '';
//   definitionForm.displayOrder = 0;
//   definitionForm.tags = [];
//   definitionForm.status = 1;
// };
const uploadRef = ref<any>();
const confirm = (schemaJson: string) => {
  return new Promise((resolve, reject) => {
    ElMessageBox.confirm('是否保存当前表单?', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    })
      .then(() => {
        formRef.value?.validate(async (valid: boolean) => {
          if (valid) {
            await uploadRef.value.uploadFilesHttp();
            const params = { ...definitionForm, categoryId };
            if (definitionForm.tags) {
              params.tags = definitionForm.tags.join(',');
            }
            if (schemaJson) {
              params.schemaJson = schemaJson;
            }
            const api = definitionForm.id ? FormAPI.editFormDefinition : FormAPI.addFormDefinition;
            api(params)
              .then(() => {
                if (definitionForm.id) {
                  ElMessage.success('编辑成功!');
                } else {
                  ElMessage.success('新增成功!');
                }
                resolve(true);
              })
              .catch(() => {
                ElMessage.error('保存失败!');
                reject(false);
              });
          }
        });
      })
      .catch(() => {
        ElMessage({ type: 'info', message: '已取消' });
        reject(false);
      });
  });
};
const handleSuccess = () => {
  console.log('success');
};
const handleChange = async (fileList: any[]) => {
  console.log('handleChange-', fileList);
  upFileList.value = fileList;
  if (definitionForm.echoUniver) {
    const excel = new ResolveExcel(fileList[0].raw);
    const excelData = await excel.readExcelFile();
    currentInstance.refs.univerSheet.createWorkbook(excelData);
  }
};
const syncUniver = (val: string | number | boolean) => {
  console.log('syncUniver-', val);
}
const handleRemove = async () => {
  const params = { ...definitionForm };
  delete params.tags;
  if (definitionForm.id) FormAPI.editFormDefinition(params);
};
const back = async () => {
  await formRef.value?.validate();
  const univerContent = currentInstance.refs.univerSheet.getData();
  univerContent.resources.forEach((v: any) => {
    if (v.name === 'SHEET_RANGE_PROTECTION_PLUGIN') {
      v.data = '';
    }
  });
  const formElements: any = [];
  formElementsMap.value.forEach((element: any) => {
    if (element.code) {
      formElements.push(toRaw(element));
    }
  });
  const formGroups = [
    {
      id: 'group1',
      name: '分组1',
      description: '分组1描述',
    },
  ];
  const formInfo = {
    formType: 'univer',
    layout: 'standard',
    showValidationSummary: false,
    submitConfirmation: false,
    formCode: definitionForm.formCode,
    formVersion: '1.0.0',
    formCategory: categoryId,
    isTemplate: true,
    validationRules: {},
  };
  const formCalculations: any = [];
  const permissions: any = [];
  for (const key in protectionRange.value) {
    permissions.push({
      position: protectionRange.value[key].position,
      meanposition: protectionRange.value[key].meanposition,
      sheetId: protectionRange.value[key].sheetId,
      sheetName: protectionRange.value[key].sheetName,
    });
  }
  const schemaJson = JSON.stringify({
    formInfo,
    univerContent,
    formElements,
    formGroups,
    formCalculations,
    permissions,
  });
  await confirm(schemaJson);
  router.push({
    path: '/form/definition',
    query: { categoryId },
  });
};
</script>

<style lang="scss" scoped>
.app-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  .op {
    display: flex;
  }
  .content {
    flex: 1;
    display: flex;
    overflow: hidden;
    .type-define-container {
      width: 290px;
      margin-left: 10px;
      height: 100%;
      :deep(.type-define-card) {
        height: 100%;
        .el-card__body {
          height: 100%;
          display: flex;
          flex-direction: column;
          .header-config-container {
            flex: 1;
            overflow-y: auto;
            margin-right: -15px;
            margin-left: 5px;
          }
        }
      }
    }
  }
}
.deform {
  margin-top: 15px;
}
.univerSheet {
  width: calc(100% - 300px);
  height: 100%;
}
#univerSheet {
  width: 100%;
  height: 800px;
  border: 1px solid #ececec;
}
.el-upload__tip {
  display: flex;
  align-items: center;
}
</style>
